#include <QMenu>
#include <QDir>
#include <QTextBrowser>
#include <QDialog>
#include <QStringList>
#include <QMenuBar>
#include <QApplication>
#include <QPixmap>
#include <string>
#include <iostream>
#include <QLabel>
#include "MainWindow.h"
#include "Board.h"
#include "TurnManager.h"
#include "NumberBoatPageWizard.h"


MainWindow :: MainWindow(QWidget *parent) : QMainWindow(parent), help(new QLabel("Inserisci le navi")), error(new QLabel("Battaglia Navale 1.0.0")), numBoat(new int[5]), dim(20) {
	namePlayer1 = new QString("Giocatore 1");
	namePlayer2 = new QString("Giocatore 2");
	creaEtichetteGiocatori();
	creaMenu();
	game = new BattleGame(dim, toDoBoatList1, toDoBoatList2);
	turnManager = TurnManager::createTurnManager("Statico 1");
	game->setTurnManager(turnManager);
	vgl = new QGridLayout(this);
	central = new QWidget(this);
	vgl->setSpacing(7);
	boardPlayer1 = new Board(dim, dim, this);
	boardPlayer2 = new Board(dim, dim, this);
	vgl->addWidget(labelPlayer1, 0, 0, 1, 1);
	vgl->addWidget(labelPlayer2, 0, 1, 1, 1);
	vgl->addWidget(boardPlayer1, 1, 0, 1, 1);
	vgl->addWidget(boardPlayer2, 1, 1, 1, 1);
	infoBox = new InformationBox(this);
	vgl->addWidget(infoBox, 1, 2, 4, 1);
	vgl->addWidget(help, 3, 0, 1, 2);
	vgl->addWidget(error, 5, 0, 1, 2);
	central->setLayout(vgl);
	setCentralWidget(central);
	connect(game, SIGNAL(helpChanged(const QString&)), help, SLOT(setText(const QString&)));
	connect(game, SIGNAL(errorChanged(const QString&)), error, SLOT(setText(const QString&)));
	connect(game, SIGNAL(numberBoatPlayer1Changed(int)), infoBox,  SLOT(setScorePlayer1(int)));
	connect(game, SIGNAL(numberBoatPlayer2Changed(int)), infoBox,  SLOT(setScorePlayer2(int)));
	connect(boardPlayer1, SIGNAL(focusOn(const Point<int>&)), game, SLOT(focusOnCampo1(const Point<int>&)));
	connect(boardPlayer1, SIGNAL(leftClickOn(const Point<int>&)), game, SLOT(leftClickedCampo1(const Point<int>&)));
	connect(boardPlayer1, SIGNAL(rightClickOn(const Point<int>&)), game, SLOT(rightClickedCampo1(const Point<int>&)));
	connect(boardPlayer1, SIGNAL(doubleClickOn(const Point<int>&)), game, SLOT(doubleClickedCampo1(const Point<int>&)));
	connect(boardPlayer2, SIGNAL(focusOn(const Point<int>&)), game, SLOT(focusOnCampo2(const Point<int>&)));
	connect(boardPlayer2, SIGNAL(leftClickOn(const Point<int>&)), game, SLOT(leftClickedCampo2(const Point<int>&)));
	connect(boardPlayer2, SIGNAL(doubleClickOn(const Point<int>&)), game, SLOT(doubleClickedCampo2(const Point<int>&)));
	connect(game, SIGNAL(arenaPlayer1Changed(Arena*)), boardPlayer1, SLOT(resetNormal(Arena*)));
	connect(game, SIGNAL(arenaPlayer2Changed(Arena*)), boardPlayer2, SLOT(resetHide(Arena*)));
	connect(game, SIGNAL(winnerPlayer1()), this, SLOT(winnerPlayer1()));
	connect(game, SIGNAL(winnerPlayer2()), this, SLOT(winnerPlayer2()));
	//Chiediamo le infomazioni di gioco
	this->reset();
}

void MainWindow :: reset() {
	//Settiamo i valori di default
	toDoBoatList1.clear();
	toDoBoatList2.clear();
	numberPage = -1;
	dim = 20;
	for (int i = 1; i < 5; ++i) numBoat[i] = 1;
	numBoat[0] = 0;
	delete turnManager;
	turnManager = TurnManager::createTurnManager("Statico 1");
	getInformation();
	infoBox->reset();
	//Ricrea le navi
	generateToDoBoatList();
	labelPlayer1->setText(*namePlayer1);
	labelPlayer2->setText(*namePlayer2);
	vgl->removeWidget(boardPlayer1);
	vgl->removeWidget(boardPlayer2);
	Board *tmp1, *tmp2;
	tmp1 = boardPlayer1;
	tmp2 = boardPlayer2; 
	boardPlayer1 = new Board(dim, dim, this);
	boardPlayer2 = new Board(dim, dim, this);
	vgl->addWidget(boardPlayer1, 1, 0, 1, 1);
	vgl->addWidget(boardPlayer2, 1, 1, 1, 1);
	vgl->addWidget(infoBox, 1, 2, 1, 1);
	//Disconnette il gioco per poterlo distruggere
	disconnect(game, 0, 0, 0);
	disconnect(boardPlayer1, 0, 0, 0);
	disconnect(boardPlayer2, 0, 0, 0);
	//Distrugge il gioco
	delete game;
	delete tmp1;
	delete tmp2;
	//Ricrea il gioco
	game = new BattleGame(dim, toDoBoatList1, toDoBoatList2);
	game->setTurnManager(turnManager);
	//Riconnette tutto
	connect(game, SIGNAL(helpChanged(const QString&)), help, SLOT(setText(const QString&)));
	connect(game, SIGNAL(errorChanged(const QString&)), error, SLOT(setText(const QString&)));
	connect(game, SIGNAL(arenaPlayer1Changed(Arena*)), boardPlayer1, SLOT(resetNormal(Arena*)));
	connect(game, SIGNAL(arenaPlayer2Changed(Arena*)), boardPlayer2, SLOT(resetHide(Arena*)));
	connect(game, SIGNAL(winnerPlayer1()), this, SLOT(winnerPlayer1()));
	connect(game, SIGNAL(winnerPlayer2()), this, SLOT(winnerPlayer2()));
	connect(game, SIGNAL(numberBoatPlayer1Changed(int)), infoBox, SLOT(setScorePlayer1(int)));
	connect(game, SIGNAL(numberBoatPlayer2Changed(int)), infoBox, SLOT(setScorePlayer2(int)));
	connect(game, SIGNAL(gameMessagePlayer1(const QString&)), infoBox, SLOT(setMessagePlayer1(const QString&)));
	connect(game, SIGNAL(gameMessagePlayer2(const QString&)), infoBox, SLOT(setMessagePlayer2(const QString&)));
	connect(boardPlayer1, SIGNAL(focusOn(const Point<int>&)), game, SLOT(focusOnCampo1(const Point<int>&)));
	connect(boardPlayer1, SIGNAL(leftClickOn(const Point<int>&)), game, SLOT(leftClickedCampo1(const Point<int>&)));
	connect(boardPlayer1, SIGNAL(rightClickOn(const Point<int>&)), game, SLOT(rightClickedCampo1(const Point<int>&)));
	connect(boardPlayer1, SIGNAL(doubleClickOn(const Point<int>&)), game, SLOT(doubleClickedCampo1(const Point<int>&)));
	connect(boardPlayer2, SIGNAL(focusOn(const Point<int>&)), game, SLOT(focusOnCampo2(const Point<int>&)));
	connect(boardPlayer2, SIGNAL(leftClickOn(const Point<int>&)), game, SLOT(leftClickedCampo2(const Point<int>&)));
	connect(boardPlayer2, SIGNAL(doubleClickOn(const Point<int>&)), game, SLOT(doubleClickedCampo2(const Point<int>&)));
}

void MainWindow :: getInformation() {
	//Pagina per chiedere i nomi
	namePlayer = new QWizardPage;
	namePlayer->setTitle(GETNAMEPLAYER);
	QLabel* textNamePlayer1 = new QLabel(GETNAMEPLAYER1);
	QLabel* textNamePlayer2 = new QLabel(GETNAMEPLAYER2);
	QLineEdit* name1Getter = new QLineEdit(namePlayer);
	QLineEdit* name2Getter = new QLineEdit(namePlayer);
	name1Getter->setMaxLength(11);
	name2Getter->setMaxLength(11);
	name1Getter->setText("Giocatore 1");
	name2Getter->setText("Giocatore 2");
	connect(name1Getter, SIGNAL(textChanged(const QString&)), this, SLOT(setNamePlayer1(const QString&)));
	connect(name2Getter, SIGNAL(textChanged(const QString&)), this, SLOT(setNamePlayer2(const QString&)));
	connect(name1Getter, SIGNAL(textChanged(const QString&)), labelPlayer1, SLOT(setText(const QString&)));
	connect(name2Getter, SIGNAL(textChanged(const QString&)), labelPlayer2, SLOT(setText(const QString&)));
	connect(name1Getter, SIGNAL(textChanged(const QString&)), infoBox, SLOT(setNamePlayer1(const QString&)));
	connect(name2Getter, SIGNAL(textChanged(const QString&)), infoBox, SLOT(setNamePlayer2(const QString&)));
	textNamePlayer1->setWordWrap(true);
	textNamePlayer2->setWordWrap(true);
	QVBoxLayout *namePlayerLayout = new QVBoxLayout;
	namePlayerLayout->addWidget(textNamePlayer1);
	namePlayerLayout->addWidget(name1Getter);
	namePlayerLayout->addWidget(textNamePlayer2);
	namePlayerLayout->addWidget(name2Getter);
	namePlayer->setLayout(namePlayerLayout);
	
	//Pagina per chiedere le dimensioni di gioco
	dimension = new QWizardPage;
	dimension->setTitle(GETDIMENSION);
	QLabel* textDimension = new QLabel(GETDIMENSIONTEXT);
	QSpinBox* dimGetter = new QSpinBox();
	dimGetter->setRange(15, 200);
	dimGetter->setSingleStep(1);
	dimGetter->setValue(20);
	connect(dimGetter, SIGNAL(valueChanged(int)), this, SLOT(setDimension(int)));
	textDimension->setWordWrap(true);
	QVBoxLayout *dimensionLayout = new QVBoxLayout;
	dimensionLayout->addWidget(textDimension);
	dimensionLayout->addWidget(dimGetter);
	dimension->setLayout(dimensionLayout);
	
	//Pagina per chiedere le regole dei turni
	turnRule = new QWizardPage;
	turnRule->setTitle(TURNRULE);
	QLabel* textTurnRule = new QLabel(TURNRULETEXT);
	QComboBox* ruleGetter = new QComboBox();
	ruleGetter->addItem("Statico 1");
	ruleGetter->addItem("Statico 2");
	ruleGetter->addItem("Statico 3");
	ruleGetter->addItem("Statico 4");
	ruleGetter->addItem("Statico 5");
	ruleGetter->addItem("Statico 6");
	ruleGetter->addItem("Statico 7");
	ruleGetter->addItem("Statico 8");
	ruleGetter->addItem("Statico 9");
	ruleGetter->addItem("Dinamico");
	connect(ruleGetter, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(setTurnManager(const QString&)));
	textTurnRule->setWordWrap(true);
	QVBoxLayout *ruleLayout = new QVBoxLayout;
	ruleLayout->addWidget(textTurnRule);
	ruleLayout->addWidget(ruleGetter);
	turnRule->setLayout(ruleLayout);
	
	wizardAircraftCarrier = new NumberBoatPageWizard(0, 2.*dim/15, AIRCRAFTCARRIER);
	wizardCruiser = new NumberBoatPageWizard(1, 2.*dim/15, CRUISER);
	wizardSubmarine = new NumberBoatPageWizard(1, 3.*dim/15, SUBMARINE);
	wizardDestroyer = new NumberBoatPageWizard(1, 3.*dim/15, DESTROYER);
	wizardCorvette = new NumberBoatPageWizard(1, 3.*dim/15, CORVETTE);
	connect(dimGetter, SIGNAL(valueChanged(int)), wizardAircraftCarrier, SLOT(setMaxNumber(int)));
	connect(dimGetter, SIGNAL(valueChanged(int)), wizardCruiser, SLOT(setMaxNumber(int)));
	connect(dimGetter, SIGNAL(valueChanged(int)), wizardSubmarine, SLOT(setMaxNumber(int)));
	connect(dimGetter, SIGNAL(valueChanged(int)), wizardDestroyer, SLOT(setMaxNumber(int)));
	connect(dimGetter, SIGNAL(valueChanged(int)), wizardCorvette, SLOT(setMaxNumber(int)));
	connect(wizardAircraftCarrier, SIGNAL(valueChanged(int)), this, SLOT(setToDoBoatList(int)));
	connect(wizardCruiser, SIGNAL(valueChanged(int)), this, SLOT(setToDoBoatList(int)));
	connect(wizardSubmarine, SIGNAL(valueChanged(int)), this, SLOT(setToDoBoatList(int)));
	connect(wizardDestroyer, SIGNAL(valueChanged(int)), this, SLOT(setToDoBoatList(int)));
	connect(wizardCorvette, SIGNAL(valueChanged(int)), this, SLOT(setToDoBoatList(int)));
	wizard = new QWizard(this);
	wizard->addPage(namePlayer);
	wizard->addPage(dimension);
	wizard->addPage(wizardAircraftCarrier);
	wizard->addPage(wizardCruiser);
	wizard->addPage(wizardSubmarine);
	wizard->addPage(wizardDestroyer);
	wizard->addPage(wizardCorvette);
	wizard->addPage(turnRule);
	wizard->setWindowTitle(GETINFORMATION);
	wizard->setWindowModality(Qt::WindowModal);
	wizard->setOption(QWizard::NoCancelButton);
	wizard->setOption(QWizard::HaveHelpButton);
	wizard->setOption(QWizard::HelpButtonOnRight);
	wizard->setWindowIcon(QIcon(QPixmap("data:velenoso.gif")));
	connect(wizard, SIGNAL(helpRequested()), this, SLOT(printHelp()));
	connect(wizard, SIGNAL(currentIdChanged(int)), this, SLOT(setNumberPage(int)));
	leftImage = new QPixmap("data:wizard.jpg", "JPG");
    wizard->setWizardStyle(QWizard::ModernStyle);
	wizard->setPixmap(QWizard::WatermarkPixmap, *leftImage);
	wizard->exec();
}

void MainWindow :: setToDoBoatList(int numberBoat) {
	numBoat[numberPage] = numberBoat;
}

void MainWindow :: generateToDoBoatList() {
	for (int i = 0; i < numBoat[4]; ++i) {
		toDoBoatList1.add(new NextBoatToDo(CORVETTE, "", 1, 1));
		toDoBoatList2.add(new NextBoatToDo(CORVETTE, "", 1, 1));
	}
	for (int i = 0; i < numBoat[3]; ++i) {
		toDoBoatList1.add(new NextBoatToDo(DESTROYER, "", 1, 2));
		toDoBoatList2.add(new NextBoatToDo(DESTROYER, "", 1, 2));
	}
	for (int i = 0; i < numBoat[2]; ++i) {
		toDoBoatList1.add(new NextBoatToDo(SUBMARINE, "", 1, 2));
		toDoBoatList2.add(new NextBoatToDo(SUBMARINE, "", 1, 2));
	}
	for (int i = 0; i < numBoat[1]; ++i) {
		toDoBoatList1.add(new NextBoatToDo(CRUISER, "", 1, 2));
		toDoBoatList2.add(new NextBoatToDo(CRUISER, "", 1, 2));
	}
	for (int i = 0; i < numBoat[0]; ++i) {
		toDoBoatList1.add(new NextBoatToDo(AIRCRAFTCARRIER, "", 1, 4));
		toDoBoatList2.add(new NextBoatToDo(AIRCRAFTCARRIER, "", 1, 4));
	}
}

void MainWindow :: setDimension(int _dim) {
	dim = _dim;
}

void MainWindow :: winnerPlayer1() {
	QMessageBox msg(QMessageBox::Information, ENDGAME, WINNER, QMessageBox::Ok, this);
	msg.exec();
	reset();
}

void MainWindow :: winnerPlayer2() {
	QMessageBox msg(QMessageBox::Information, ENDGAME, LOSER, QMessageBox::Ok, this);
	msg.exec();
	reset();
}

void MainWindow :: setTurnManager(const QString& name) {
	delete turnManager;
	turnManager = TurnManager::createTurnManager(name.toStdString());
}

void MainWindow :: printHelp() {
	QTextBrowser* help = new QTextBrowser(this);
	QDir home = QDir::current();
	help->setSource(QUrl::fromLocalFile(home.filePath("data:help.htm")));
	QString test = (QUrl::fromLocalFile(home.filePath("data:help.htm"))).toString();
	QDialog* helpWindow = new QDialog(this);
	QBoxLayout* layout = new QBoxLayout(QBoxLayout::TopToBottom, helpWindow);
	layout->addWidget(help);
	helpWindow->setLayout(layout);
	helpWindow->show();
}

void MainWindow :: creaEtichetteGiocatori() {
	QString tmp("<h2>"), tmp2("<h2>");
	labelPlayer1 = new QLabel(tmp.append(*namePlayer1).append("<\\h2>"));
	labelPlayer2 = new QLabel(tmp2.append(*namePlayer2).append("<\\h2>"));
}

void MainWindow :: creaMenu() {
	QAction *reset = new QAction(tr(NEWGAMEMENU), this);
	QAction *quit = new QAction(tr(EXITMENU), this);
	QAction *guida = new QAction(tr(GUIDAMENU), this);
	QAction *about = new QAction(tr(ABOUTMENU), this);
	QMenu *file;
	QMenu *helpMenu;
	file = menuBar()->addMenu(tr(GAMEMENU));
	file->addAction(reset);
	file->addAction(quit);
	helpMenu = menuBar()->addMenu(tr(HELPMENU));
	helpMenu->addAction(guida);
	helpMenu->addAction(about);
	connect(quit, SIGNAL(triggered()), qApp, SLOT(quit()));
	connect(reset, SIGNAL(triggered()), this, SLOT(reset()));
	connect(guida, SIGNAL(triggered()), this, SLOT(printHelp()));
	connect(about, SIGNAL(triggered()), this, SLOT(about()));
}

void MainWindow :: setNumberPage(int) {
	if (wizard->currentPage() == wizardAircraftCarrier) numberPage = 0;
	else if (wizard->currentPage() == wizardCruiser) numberPage = 1;
	else if (wizard->currentPage() == wizardSubmarine) numberPage = 2;
	else if (wizard->currentPage() == wizardDestroyer) numberPage = 3;
	else if (wizard->currentPage() == wizardCorvette) numberPage = 4;
	else numberPage = 0;
}

void MainWindow :: setNamePlayer1(const QString& _name) {
	delete namePlayer1;
	namePlayer1 = new QString(_name);
}

void MainWindow :: setNamePlayer2(const QString& _name) {
	delete namePlayer2;
	namePlayer2 = new QString(_name);
}

void MainWindow :: about() {
	QMessageBox::information(this, ABOUT, AUTHOR, OK);
}

